//******************************COPYRIGHT NOTICE*******************************
//All rights reserved.  This material is confidential and proprietary to 
//CogentSoft (Shen Zhen) Limited and no part of this material should be reproduced, 
//published in any form by any means, electronic or mechanical including
//photocopy or any information storage or retrieval system nor should the
//material be disclosed to third parties without the express written 
//authorization of CogentSoft (Shen Zhen) Limited.
/*
 <PRE>
 * **************************VSS GENERATED VERSION NUMBER************************
 * $Revision: $
 * ******************************PROGRAM DESCRIPTION*****************************
 * Program Name   : BaseUtil.java
 * Description: BaseUtil object
 * Creation Date  : 2006-4-19
 * Creator: 系统组

 * ******************************MODIFICATION HISTORY****************************
 * Modify Date: [Date in YYYY/MM/DD]
 * Modifier   : [Developer Name]
 * CR / SIR No.   : [Cogentˇs CR / SIR No.]
 * Description: [Description]
 * ******************************************************************************
 </PRE>
 */

/**
 * BaseUtil object
 * 
 * <DT><B>Copyright:</B>
 * <DD>The contents of this file are confidential and proprietary to Cogent.</DD>
 * <DD>Copying is explicitly prohibited without the express permission of Cogent.</DD>
 * 
 * @author LQ
 * @version 1.0
 *
 */
package com.cogent.common.util;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.BreakIterator;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang.StringUtils;
import org.apache.oro.text.perl.Perl5Util;

@SuppressWarnings("unchecked")
public class BaseUtil {
    
    // Constants used by escapeHTMLTags
    private static final char[] QUOTE_ENCODE = "&quot;".toCharArray();

    private static final char[] AMP_ENCODE = "&amp;".toCharArray();

    private static final char[] LT_ENCODE = "&lt;".toCharArray();

    // private static final char[] GT_ENCODE = "&gt;".toCharArray();

    /** 降序排序　*/
    private static final String DESC = "1";

    /**
     * Replaces all instances of oldString with newString in line with the added
     * feature that matches of newString in oldString ignore case.
     * 
     * @param line
     *            the String to search to perform replacements on
     * @param oldString
     *            the String that should be replaced by newString
     * @param newString
     *            the String that will replace all instances of oldString
     * 
     * @return a String will all instances of oldString replaced by newString
     */
    public static final String replaceIgnoreCase(String line, String oldString, String newString) {
        if (line == null) {
            return null;
        }
        String lcLine = line.toLowerCase();
        String lcOldString = oldString.toLowerCase();
        int i = 0;
        if ((i = lcLine.indexOf(lcOldString, i)) >= 0) {
            char[] line2 = line.toCharArray();
            char[] newString2 = newString.toCharArray();
            int oLength = oldString.length();
            StringBuffer buf = new StringBuffer(line2.length);
            buf.append(line2, 0, i).append(newString2);
            i += oLength;
            int j = i;
            while ((i = lcLine.indexOf(lcOldString, i)) > 0) {
                buf.append(line2, j, i - j).append(newString2);
                i += oLength;
                j = i;
            }
            buf.append(line2, j, line2.length - j);
            return buf.toString();
        }
        return line;
    }

    /**
     * Replaces all instances of oldString with newString in line with the added
     * feature that matches of newString in oldString ignore case. The count
     * paramater is set to the number of replaces performed.
     * 
     * @param line
     *            the String to search to perform replacements on
     * @param oldString
     *            the String that should be replaced by newString
     * @param newString
     *            the String that will replace all instances of oldString
     * @param count
     *            a value that will be updated with the number of replaces
     *            performed.
     * 
     * @return a String will all instances of oldString replaced by newString
     */
    public static final String replaceIgnoreCase(String line, String oldString, String newString, int[] count) {
        if (line == null) {
            return null;
        }
        String lcLine = line.toLowerCase();
        String lcOldString = oldString.toLowerCase();
        int i = 0;
        if ((i = lcLine.indexOf(lcOldString, i)) >= 0) {
            int counter = 0;
            char[] line2 = line.toCharArray();
            char[] newString2 = newString.toCharArray();
            int oLength = oldString.length();
            StringBuffer buf = new StringBuffer(line2.length);
            buf.append(line2, 0, i).append(newString2);
            i += oLength;
            int j = i;
            while ((i = lcLine.indexOf(lcOldString, i)) > 0) {
                counter++;
                buf.append(line2, j, i - j).append(newString2);
                i += oLength;
                j = i;
            }
            buf.append(line2, j, line2.length - j);
            count[0] = counter;
            return buf.toString();
        }
        return line;
    }

    /**
     * Replaces all instances of oldString with newString in line. The count
     * Integer is updated with number of replaces.
     * 
     * @param line
     *            the String to search to perform replacements on
     * @param oldString
     *            the String that should be replaced by newString
     * @param newString
     *            the String that will replace all instances of oldString
     * 
     * @return a String will all instances of oldString replaced by newString
     */
    public static final String replace(String line, String oldString, String newString, int[] count) {
        if (line == null) {
            return null;
        }
        int i = 0;
        if ((i = line.indexOf(oldString, i)) >= 0) {
            int counter = 0;
            counter++;
            char[] line2 = line.toCharArray();
            char[] newString2 = newString.toCharArray();
            int oLength = oldString.length();
            StringBuffer buf = new StringBuffer(line2.length);
            buf.append(line2, 0, i).append(newString2);
            i += oLength;
            int j = i;
            while ((i = line.indexOf(oldString, i)) > 0) {
                counter++;
                buf.append(line2, j, i - j).append(newString2);
                i += oLength;
                j = i;
            }
            buf.append(line2, j, line2.length - j);
            count[0] = counter;
            return buf.toString();
        }
        return line;
    }

    /**
     * 从右边向左取分隔符右边的值.
     * @param source
     *            原始文本.
     * @param sep
     *            分隔符.
     */
    public static String rRight(String source, String sep) {
        String retstr = "";
        int len = source.length();
        int len1 = sep.length();
        int len2 = len - len1;
        for (int i = len2 - 1; i >= 0; i--) {
            if (source.substring(i, i + len1).equals(sep)) {
                retstr = source.substring(i + len1, len);
                break;
            }
        }
        return retstr;
    }

    /**
     * 从右边向左取分隔符左边的值.
     * @param source
     *            原始文本.
     * @param sep
     *            分隔符.
     */
    public static String rLeft(String source, String sep) {
        String retstr = "";
        int len = source.length();
        int len1 = sep.length();
        int len2 = len - len1;
        for (int i = len2 - 1; i >= 0; i--) {
            if (source.substring(i, i + len1).equals(sep)) {
                retstr = source.substring(0, i);
                break;
            }
        }
        return retstr;
    }

    /**
     * 从左边向右取分隔符左边的值.
     * @param source
     *            原始文本.
     * @param sep
     *            分隔符.
     */
    public static String lLeft(String source, String sep) {
        String retstr = "";
        int i;
        i = source.indexOf(sep);
        if (i > 0) {
            retstr = source.substring(0, i);
        }
        return retstr;
    }

    /**
     * 从左边向右取分隔符右边的值.
     * @param source
     *            原始文本.
     * @param sep
     *            分隔符.
     */
    public static String lRight(String source, String sep) {
        String retstr = "";
        int i;
        int len = source.length();
        int len1 = sep.length();
        i = source.indexOf(sep);
        if (i > 0) {
            retstr = source.substring(i + len1, len);
        }
        return retstr;
    }

    /**
     * Used by the hash method.
     */
    private static MessageDigest digest = null;

    /**
     * Hashes a String using the Md5 algorithm and returns the result as a
     * String of hexadecimal numbers. This method is synchronized to avoid
     * excessive MessageDigest object creation. If calling this method becomes a
     * bottleneck in your code, you may wish to maintain a pool of MessageDigest
     * objects instead of using this method.
     * <p>
     * A hash is a one-way function -- that is, given an input, an output is
     * easily computed. However, given the output, the input is almost
     * impossible to compute. This is useful for passwords since we can store
     * the hash and a hacker will then have a very hard time determining the
     * original password.
     * <p>
     * every time a user logs in, we simply take their plain text password,
     * compute the hash, and compare the generated hash to the stored hash.
     * Since it is almost impossible that two passwords will generate the same
     * hash, we know if the user gave us the correct password or not. The only
     * negative to this system is that password recovery is basically
     * impossible. Therefore, a reset password method is used instead.
     * 
     * @param data
     *            the String to compute the hash of.
     * @return a hashed version of the passed-in String
     */
    public synchronized static final String hash(String data) {
        if (digest == null) {
            try {
                digest = MessageDigest.getInstance("MD5");
            } catch (NoSuchAlgorithmException nsae) {
                System.err.println("Failed to load the MD5 MessageDigest.");
                nsae.printStackTrace();
            }
        }
        // Now, compute hash.
        digest.update(data.getBytes());
        return encodeHex(digest.digest());
    }

    /**
     * 
     * @param s
     * @return
     */
    public static String toUtf8String(String s) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (c >= 0 && c <= 255) {
                sb.append(c);
            } else {
                byte[] b;
                try {
                    b = Character.toString(c).getBytes("utf-8");
                } catch (Exception ex) {
                    b = new byte[0];
                }
                for (int j = 0; j < b.length; j++) {
                    int k = b[j];
                    if (k < 0)
                        k += 256;
                    sb.append("%" + Integer.toHexString(k).toUpperCase());
                }
            }
        }
        return sb.toString();
    }

    /**
     * Turns an array of bytes into a String representing each byte as an
     * unsigned hex number.
     * 
     * @param bytes
     *            an array of bytes to convert to a hex-string
     * @return generated hex string
     */
    public static final String encodeHex(byte[] bytes) {
        StringBuffer buf = new StringBuffer(bytes.length * 2);
        int i;

        for (i = 0; i < bytes.length; i++) {
            if (((int) bytes[i] & 0xff) < 0x10) {
                buf.append("0");
            }
            buf.append(Long.toString((int) bytes[i] & 0xff, 16));
        }
        return buf.toString();
    }

    /**
     * Turns a hex encoded string into a byte array. It is specifically meant to
     * "reverse" the toHex(byte[]) method.
     * 
     * @param hex
     *            a hex encoded String to transform into a byte array.
     * @return a byte array representing the hex String[
     */
    public static final byte[] decodeHex(String hex) {
        char[] chars = hex.toCharArray();
        byte[] bytes = new byte[chars.length / 2];
        int byteCount = 0;
        for (int i = 0; i < chars.length; i += 2) {
            byte newByte = 0x00;
            newByte |= hexCharToByte(chars[i]);
            newByte <<= 4;
            newByte |= hexCharToByte(chars[i + 1]);
            bytes[byteCount] = newByte;
            byteCount++;
        }
        return bytes;
    }

    /**
     * Returns the the byte value of a hexadecmical char (0-f). It's assumed
     * that the hexidecimal chars are lower case as appropriate.
     * 
     * @param ch
     *            a hexedicmal character (0-f)
     * @return the byte value of the character (0x00-0x0F)
     */
    private static final byte hexCharToByte(char ch) {
        switch (ch) {
        case '0':
            return 0x00;
        case '1':
            return 0x01;
        case '2':
            return 0x02;
        case '3':
            return 0x03;
        case '4':
            return 0x04;
        case '5':
            return 0x05;
        case '6':
            return 0x06;
        case '7':
            return 0x07;
        case '8':
            return 0x08;
        case '9':
            return 0x09;
        case 'a':
            return 0x0A;
        case 'b':
            return 0x0B;
        case 'c':
            return 0x0C;
        case 'd':
            return 0x0D;
        case 'e':
            return 0x0E;
        case 'f':
            return 0x0F;
        }
        return 0x00;
    }

    /**
     * Encodes a String as a base64 String.
     * 
     * @param data
     *            a String to encode.
     * @return a base64 encoded String.
     */
    public static String encodeBase64(String data) {
        return encodeBase64(data.getBytes());
    }

    /**
     * Encodes a byte array into a base64 String.
     * 
     * @param data
     *            a byte array to encode.
     * @return a base64 encode String.
     */
    public static String encodeBase64(byte[] data) {
        int c;
        int len = data.length;
        StringBuffer ret = new StringBuffer(((len / 3) + 1) * 4);
        for (int i = 0; i < len; ++i) {
            c = (data[i] >> 2) & 0x3f;
            ret.append(cvt.charAt(c));
            c = (data[i] << 4) & 0x3f;
            if (++i < len) {
                c |= (data[i] >> 4) & 0x0f;

            }
            ret.append(cvt.charAt(c));
            if (i < len) {
                c = (data[i] << 2) & 0x3f;
                if (++i < len) {
                    c |= (data[i] >> 6) & 0x03;

                }
                ret.append(cvt.charAt(c));
            } else {
                ++i;
                ret.append((char) fillchar);
            }

            if (i < len) {
                c = data[i] & 0x3f;
                ret.append(cvt.charAt(c));
            } else {
                ret.append((char) fillchar);
            }
        }
        return ret.toString();
    }

    /**
     * Decodes a base64 String.
     * 
     * @param data
     *            a base64 encoded String to decode.
     * @return the decoded String.
     */
    public static String decodeBase64(String data) {
        return decodeBase64(data.getBytes());
    }

    /**
     * Decodes a base64 aray of bytes.
     * 
     * @param data
     *            a base64 encode byte array to decode.
     * @return the decoded String.
     */
    public static String decodeBase64(byte[] data) {
        int c, c1;
        int len = data.length;
        StringBuffer ret = new StringBuffer((len * 3) / 4);
        for (int i = 0; i < len; ++i) {
            c = cvt.indexOf(data[i]);
            ++i;
            c1 = cvt.indexOf(data[i]);
            c = ((c << 2) | ((c1 >> 4) & 0x3));
            ret.append((char) c);
            if (++i < len) {
                c = data[i];
                if (fillchar == c) {
                    break;
                }

                c = cvt.indexOf((char) c);
                c1 = ((c1 << 4) & 0xf0) | ((c >> 2) & 0xf);
                ret.append((char) c1);
            }

            if (++i < len) {
                c1 = data[i];
                if (fillchar == c1) {
                    break;
                }

                c1 = cvt.indexOf((char) c1);
                c = ((c << 6) & 0xc0) | c1;
                ret.append((char) c);
            }
        }
        return ret.toString();
    }

    private static final int fillchar = '=';

    private static final String cvt = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/";

    /**
     * Converts a line of text into an array of lower case words using a
     * BreakIterator.wordInstance().
     * <p>
     * 
     * @param text
     *            a String of text to convert into an array of words
     * @return text broken up into an array of words.
     */
    public static final String[] toLowerCaseWordArray(String text) {
        if (text == null || text.length() == 0) {
            return new String[0];
        }

        ArrayList wordList = new ArrayList();
        BreakIterator boundary = BreakIterator.getWordInstance();
        boundary.setText(text);
        int start = 0;

        for (int end = boundary.next(); end != BreakIterator.DONE; start = end, end = boundary.next()) {
            String tmp = text.substring(start, end).trim();
            // Remove characters that are not needed.
            tmp = replace(tmp, "+", "");
            tmp = replace(tmp, "/", "");
            tmp = replace(tmp, "\\", "");
            tmp = replace(tmp, "#", "");
            tmp = replace(tmp, "*", "");
            tmp = replace(tmp, ")", "");
            tmp = replace(tmp, "(", "");
            tmp = replace(tmp, "&", "");
            if (tmp.length() > 0) {
                wordList.add(tmp);
            }
        }
        return (String[]) wordList.toArray(new String[wordList.size()]);
    }

    /**
     * Pseudo-random number generator object for use with randomString(). The
     * Random class is not considered to be cryptographically secure, so only
     * use these random Strings for low to medium security applications.
     */
    private static Random randGen = new Random();

    /**
     * Array of numbers and letters of mixed case. Numbers appear in the list
     * twice so that there is a more equal chance that a number will be picked.
     * We can use the array to get a random number or letter by picking a random
     * array index.
     */
    private static char[] numbersAndLetters = ("0123456789abcdefghijklmnopqrstuvwxyz"
            + "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ").toCharArray();

    /**
     * Returns a random String of numbers and letters (lower and upper case) of
     * the specified length. The method uses the Random class that is built-in
     * to Java which is suitable for low to medium grade security uses. This
     * means that the output is only pseudo random, i.e., each number is
     * mathematically generated so is not truly random.
     * <p>
     * 
     * The specified length must be at least one. If not, the method will return
     * null.
     * 
     * @param length
     *            the desired length of the random String to return.
     * @return a random String of numbers and letters of the specified length.
     */
    public static final String randomString(int length) {
        if (length < 1) {
            return null;
        }
        // Create a char buffer to put random letters and numbers in.
        char[] randBuffer = new char[length];
        for (int i = 0; i < randBuffer.length; i++) {
            randBuffer[i] = numbersAndLetters[randGen.nextInt(71)];
        }
        return new String(randBuffer);
    }

    /**
     * Intelligently chops a String at a word boundary (whitespace) that occurs
     * at the specified index in the argument or before. However, if there is a
     * newline character before <code>length</code>, the String will be
     * chopped there. If no newline or whitespace is found in
     * <code>string</code> up to the index <code>length</code>, the String
     * will chopped at <code>length</code>.
     * <p>
     * For example, chopAtWord("This is a nice String", 10) will return "This is
     * a" which is the first word boundary less than or equal to 10 characters
     * into the original String.
     * 
     * @param string
     *            the String to chop.
     * @param length
     *            the index in <code>string</code> to start looking for a
     *            whitespace boundary at.
     * @return a substring of <code>string</code> whose length is less than or
     *         equal to <code>length</code>, and that is chopped at
     *         whitespace.
     */
    public static final String chopAtWord(String string, int length) {
        if (string == null) {
            return string;
        }

        char[] charArray = string.toCharArray();
        int sLength = string.length();
        if (length < sLength) {
            sLength = length;
        }

        // First check if there is a newline character before length; if so,
        // chop word there.
        for (int i = 0; i < sLength - 1; i++) {
            // Windows
            if (charArray[i] == '\r' && charArray[i + 1] == '\n') {
                return string.substring(0, i + 1);
            }
            // Unix
            else if (charArray[i] == '\n') {
                return string.substring(0, i);
            }
        }
        // Also check boundary case of Unix newline
        if (charArray[sLength - 1] == '\n') {
            return string.substring(0, sLength - 1);
        }

        // Done checking for newline, now see if the total string is less than
        // the specified chop point.
        if (string.length() < length) {
            return string;
        }

        // No newline, so chop at the first whitespace.
        for (int i = length - 1; i > 0; i--) {
            if (charArray[i] == ' ') {
                return string.substring(0, i).trim();
            }
        }

        // Did not find word boundary so return original String chopped at
        // specified length.
        return string.substring(0, length);
    }

    // Create a regular expression engine that is used by the highlightWords
    // method below.
    private static Perl5Util perl5Util = new Perl5Util();

    /**
     * Highlights words in a string. Words matching ignores case. The actual
     * higlighting method is specified with the start and end higlight tags.
     * Those might be beginning and ending HTML bold tags, or anything else.
     * <p>
     * 
     * This method is under the Jive Open Source Software License and was
     * written by Mark Imbriaco.
     * 
     * @param string
     *            the String to highlight words in.
     * @param words
     *            an array of words that should be highlighted in the string.
     * @param startHighlight
     *            the tag that should be inserted to start highlighting.
     * @param endHighlight
     *            the tag that should be inserted to end highlighting.
     * @return a new String with the specified words highlighted.
     */
    public static final String highlightWords(String string, String[] words, String startHighlight, String endHighlight) {
        if (string == null || words == null || startHighlight == null || endHighlight == null) {
            return null;
        }

        StringBuffer regexp = new StringBuffer();

        // Iterate through each word and generate a word list for the regexp.
        for (int x = 0; x < words.length; x++) {
            // Excape "|" and "/" to keep us out of trouble in our regexp.
            words[x] = perl5Util.substitute("s#([\\|\\/\\.])#\\\\$1#g", words[x]);
            if (regexp.length() > 0) {
                regexp.append("|");
            }
            regexp.append(words[x]);
        }

        // Escape the regular expression delimiter ("/").
        startHighlight = perl5Util.substitute("s#\\/#\\\\/#g", startHighlight);
        endHighlight = perl5Util.substitute("s#\\/#\\\\/#g", endHighlight);

        // Build the regular expression. insert() the first part.
        regexp.insert(0, "s/\\b(");
        // The word list is here already, so just append the rest.
        regexp.append(")\\b/");
        regexp.append(startHighlight);
        regexp.append("$1");
        regexp.append(endHighlight);
        regexp.append("/igm");

        // Do the actual substitution via a simple regular expression.
        return perl5Util.substitute(regexp.toString(), string);
    }

    /**
     * Escapes all necessary characters in the String so that it can be used in
     * an XML doc.
     * 
     * @param string
     *            the string to escape.
     * @return the string with appropriate characters escaped.
     */
    public static final String escapeForXML(String string) {
        if (string == null) {
            return null;
        }
        char ch;
        int i = 0;
        int last = 0;
        char[] input = string.toCharArray();
        int len = input.length;
        StringBuffer out = new StringBuffer((int) (len * 1.3));
        for (; i < len; i++) {
            ch = input[i];
            if (ch > '>') {
                continue;
            } else if (ch == '<') {
                if (i > last) {
                    out.append(input, last, i - last);
                }
                last = i + 1;
                out.append(LT_ENCODE);
            } else if (ch == '&') {
                if (i > last) {
                    out.append(input, last, i - last);
                }
                last = i + 1;
                out.append(AMP_ENCODE);
            } else if (ch == '"') {
                if (i > last) {
                    out.append(input, last, i - last);
                }
                last = i + 1;
                out.append(QUOTE_ENCODE);
            }
        }
        if (last == 0) {
            return string;
        }
        if (i > last) {
            out.append(input, last, i - last);
        }
        return out.toString();
    }

    /**
     * Unescapes the String by converting XML escape sequences back into normal
     * characters.
     * 
     * @param string
     *            the string to unescape.
     * @return the string with appropriate characters unescaped.
     */
    public static final String unescapeFromXML(String string) {
        string = replace(string, "&lt;", "<");
        string = replace(string, "&gt;", ">");
        string = replace(string, "&quot;", "\"");
        return replace(string, "&amp;", "&");
    }

    private static final char[] zeroArray = "0000000000000000".toCharArray();

    /**
     * Pads the supplied String with 0's to the specified length and returns the
     * result as a new String. For example, if the initial String is "9999" and
     * the desired length is 8, the result would be "00009999". This type of
     * padding is useful for creating numerical values that need to be stored
     * and sorted as character data. Note: the current implementation of this
     * method allows for a maximum <tt>length</tt> of 16.
     * 
     * @param string
     *            the original String to pad.
     * @param length
     *            the desired length of the new padded String.
     * @return a new String padded with the required number of 0's.
     */
    public static final String zeroPadString(String string, int length) {
        if (string == null || string.length() > length) {
            return string;
        }
        StringBuffer buf = new StringBuffer(length);
        buf.append(zeroArray, 0, length - string.length()).append(string);
        return buf.toString();
    }

    /**
     * Formats a Date as a fifteen character long String made up of the Date's
     * padded millisecond value.
     * 
     * @return a Date encoded as a String.
     */
    public static final String dateToMillis(Date date) {
        return zeroPadString(Long.toString(date.getTime()), 15);
    }

    public static String convertNull(String s) {
        if (s == null) {
            return "";
        }
        return s;
    }

    public static String gbToAscText(String gbString) {
        gbString = BaseUtil.convertNull(gbString);
        try {
            gbString = BaseUtil.convertNull(gbString);
            String ascString = new String(gbString.getBytes("GBK"), "ISO8859_1");
            return ascString;
        } catch (UnsupportedEncodingException e1) {
            return gbString;
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    public static String ascToGbText(String ascString) {
        ascString = BaseUtil.convertNull(ascString);
        try {
            ascString = BaseUtil.convertNull(ascString);
            String gbString = new String(ascString.getBytes("ISO8859_1"), "GBK");
            return gbString;
        } catch (UnsupportedEncodingException e1) {
            return ascString;
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    public static String gbToAsc(String gbString) {
        gbString = BaseUtil.convertNull(gbString);

        try {
            String ascString = new String(gbString.getBytes("GB2312"), "ISO8859_1");
            return ascString;
        } catch (UnsupportedEncodingException e1) {
            return gbString;
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }

    }

    public static String ascToGb(String ascString) {
        ascString = BaseUtil.convertNull(ascString);

        try {
            ascString = BaseUtil.convertNull(ascString);
            String gbString = new String(ascString.getBytes("ISO8859_1"), "GB2312");
            return gbString;
        } catch (UnsupportedEncodingException e1) {
            return ascString;
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    /**
     * Get the year select option,and the current year is the given year.
     * 
     * @param currentYear
     * @return
     */
    public static String getYearOption(int currentYear) {
        StringBuffer yearOption = new StringBuffer("");
        for (int i = 2006; i < 2021; i++) {
            if (i == currentYear)
                yearOption.append("<option value='" + i + "' selected>" + i + "</option>");
            else
                yearOption.append("<option value='" + i + "'>" + i + "</option>");
        }
        return yearOption.toString();
    }

    /**
     * Get the month select option,and the current month is the given month.
     * 
     * @param currentMonth
     * @return
     */
    public static String getMonthOption(int currentMonth) {
        StringBuffer monthOption = new StringBuffer("");
        for (int i = 1; i < 13; i++) {
            if (i == currentMonth)
                monthOption.append("<option value='" + i + "' selected>" + i + "</option>");
            else
                monthOption.append("<option value='" + i + "'>" + i + "</option>");
        }
        return monthOption.toString();
    }

    public static List quoteStrList(List list) {
        List tmpList = list;
        list = new ArrayList();
        Iterator i = tmpList.iterator();
        while (i.hasNext()) {
            String str = (String) i.next();
            str = "'" + str + "'";
            list.add(str);
        }
        return list;
    }

    public static String join(List list, String delim) {
        if (list == null || list.size() < 1)
            return null;
        StringBuffer buf = new StringBuffer();
        Iterator i = list.iterator();
        while (i.hasNext()) {
            buf.append((String) i.next());
            if (i.hasNext())
                buf.append(delim);
        }
        return buf.toString();
    }

    public static List split(String str, String delim) {
        List splitList = null;
        StringTokenizer st = null;

        if (str == null)
            return splitList;

        if (delim != null)
            st = new StringTokenizer(str, delim);
        else
            st = new StringTokenizer(str);

        if (st != null && st.hasMoreTokens()) {
            splitList = new ArrayList();

            while (st.hasMoreTokens())
                splitList.add(st.nextToken());
        }
        return splitList;
    }

    public static String createBreaks(String input, int maxLength) {
        char chars[] = input.toCharArray();
        int len = chars.length;
        StringBuffer buf = new StringBuffer(len);
        int count = 0;
        int cur = 0;
        for (int i = 0; i < len; i++) {
            if (Character.isWhitespace(chars[i]))
                count = 0;
            if (count >= maxLength) {
                count = 0;
                buf.append(chars, cur, i - cur).append(" ");
                cur = i;
            }
            count++;
        }
        buf.append(chars, cur, len - cur);
        return buf.toString();
    }

    /**
     * Escape SQL tags, ' to ''; \ to \\.
     * 
     * @param input
     *            string to replace
     * @return string
     */
    public static String escapeSQLTags(String input) {
        if (input == null || input.length() == 0)
            return input;
        StringBuffer buf = new StringBuffer();
        char ch = ' ';
        for (int i = 0; i < input.length(); i++) {
            ch = input.charAt(i);
            if (ch == '\\')
                buf.append("\\\\");
            else if (ch == '\'')
                buf.append("\'\'");
            else
                buf.append(ch);
        }
        return buf.toString();
    }

    /**
     * Escape HTML tags.
     * 
     * @param input
     *            string to replace
     * @return string
     */
    public static String escapeHTMLTags(String input) {
        if (input == null || input.length() == 0)
            return input;
        StringBuffer buf = new StringBuffer();
        char ch = ' ';
        for (int i = 0; i < input.length(); i++) {
            ch = input.charAt(i);
            if (ch == '<')
                buf.append("&lt;");
            else if (ch == '>')
                buf.append("&gt;");
            else if (ch == '&')
                buf.append("&amp;");
            else if (ch == '"')
                buf.append("&quot;");
            else
                buf.append(ch);
        }
        return buf.toString();
    }

    /**
     * Convert new lines, \n or \r\n to <BR />.
     * 
     * @param input
     *            string to convert
     * @return string
     */
    public static String convertNewlines(String input) {
        input = replace(input, "\r\n", "\n");
        input = replace(input, "\n", "<BR />");
        return input;
    }

    public static String replace(String mainString, String oldString, String newString) {
        if (mainString == null)
            return null;
        int i = mainString.lastIndexOf(oldString);
        if (i < 0)
            return mainString;
        StringBuffer mainSb = new StringBuffer(mainString);
        while (i >= 0) {
            mainSb.replace(i, i + oldString.length(), newString);
            i = mainString.lastIndexOf(oldString, i - 1);
        }
        return mainSb.toString();
    }

    /**
     * Check a string null or blank.
     * 
     * @param param
     *            string to check
     * @return boolean
     */
    public static boolean nullOrBlank(String param) {
        return (param == null || param.trim().equals("")) ? true : false;
    }

    public static String notNull(String param) {
        return param == null ? "" : param.trim();
    }

    /**
     * Parse a string to int.
     * 
     * @param param
     *            string to parse
     * @return int value, on exception return 0.
     */

    public static int parseInt(String param) {
        int i = 0;
        try {
            i = Integer.parseInt(param);
        } catch (Exception e) {
            i = (int) parseFloat(param);
        }
        return i;
    }

    public static long parseLong(String param) {
        long l = 0;
        try {
            l = Long.parseLong(param);
        } catch (Exception e) {
            l = (long) parseDouble(param);
        }
        return l;
    }

    public static float parseFloat(String param) {
        float f = 0;
        try {
            f = Float.parseFloat(param);
        } catch (Exception e) {
            //
        }
        return f;
    }

    public static double parseDouble(String param) {
        double d = 0;
        try {
            d = Double.parseDouble(param);
        } catch (Exception e) {
            //
        }
        return d;
    }

    /**
     * Parse a string to boolean.
     * 
     * @param param
     *            string to parse
     * @return boolean value, if param begin with(1,y,Y,t,T) return true, on
     *         exception return false.
     */
    public static boolean parseBoolean(String param) {
        if (nullOrBlank(param))
            return false;
        switch (param.charAt(0)) {
        case '1':
        case 'y':
        case 'Y':
        case 't':
        case 'T':
            return true;
        }
        return false;
    }

    /**
     * Convert URL .
     * 
     * @param input
     *            string to convert
     * @return string
     */
    public static String convertURL(String input) {
        if (input == null || input.length() == 0)
            return input;
        StringBuffer buf = new StringBuffer(input.length() + 25);
        char chars[] = input.toCharArray();
        int len = input.length();
        int index = -1;
        int i = 0;
        int j = 0;
        int oldend = 0;
        while (++index < len) {
            char cur = chars[i = index];
            j = -1;
            if ((cur == 'f' && index < len - 6 && chars[++i] == 't' && chars[++i] == 'p' || cur == 'h'
                    && (i = index) < len - 7 && chars[++i] == 't' && chars[++i] == 't' && chars[++i] == 'p'
                    && (chars[++i] == 's' || chars[--i] == 'p'))
                    && i < len - 4 && chars[++i] == ':' && chars[++i] == '/' && chars[++i] == '/')
                j = ++i;
            if (j > 0) {
                if (index == 0 || (cur = chars[index - 1]) != '\'' && cur != '"' && cur != '<' && cur != '=') {
                    cur = chars[j];
                    while (j < len) {
                        if (cur == ' ' || cur == '\t' || cur == '\'' || cur == '"' || cur == '<' || cur == '['
                                || cur == '\n' || cur == '\r' && j < len - 1 && chars[j + 1] == '\n')
                            break;
                        if (++j < len)
                            cur = chars[j];
                    }
                    cur = chars[j - 1];
                    if (cur == '.' || cur == ',' || cur == ')' || cur == ']')
                        j--;
                    buf.append(chars, oldend, index - oldend);
                    buf.append("<a href=\"");
                    buf.append(chars, index, j - index);
                    buf.append('"');
                    buf.append(" target=\"_blank\"");
                    buf.append('>');
                    buf.append(chars, index, j - index);
                    buf.append("</a>");
                } else {
                    buf.append(chars, oldend, j - oldend);
                }
                oldend = index = j;
            } else if (cur == '[' && index < len - 6 && chars[i = index + 1] == 'u' && chars[++i] == 'r'
                    && chars[++i] == 'l' && (chars[++i] == '=' || chars[i] == ' ')) {
                j = ++i;
                int u2;
                int u1 = u2 = input.indexOf("]", j);
                if (u1 > 0)
                    u2 = input.indexOf("[/url]", u1 + 1);
                if (u2 < 0) {
                    buf.append(chars, oldend, j - oldend);
                    oldend = j;
                } else {
                    buf.append(chars, oldend, index - oldend);
                    buf.append("<a href =\"");
                    String href = input.substring(j, u1).trim();
                    if (href.indexOf("javascript:") == -1 && href.indexOf("file:") == -1)
                        buf.append(href);
                    buf.append("\" target=\"_blank");
                    buf.append("\">");
                    buf.append(input.substring(u1 + 1, u2).trim());
                    buf.append("</a>");
                    oldend = u2 + 6;
                }
                index = oldend;
            }
        }
        if (oldend < len)
            buf.append(chars, oldend, len - oldend);
        return buf.toString();
    }

    /**
     * Display a string in html page, call methods: escapeHTMLTags, convertURL,
     * convertNewlines.
     * 
     * @param input
     *            string to display
     * @return string
     */
    public static String dspHtml(String input) {
        String str = input;
        str = createBreaks(str, 80);
        str = escapeHTMLTags(str);
        str = convertURL(str);
        str = convertNewlines(str);
        return str;
    }

    public static String timestampGetHour(String time) {
        int j = time.indexOf(":");
        if (j <= 0)
            return "";
        String hour = time.substring(j - 2, time.length());
        return hour;
    }

    /**
     * 将指定字符串截断，超过部分用“...”代替.
     * @param source
     *            原字符.
     * @param len
     *            长度.
     */
    public static String getSubString(String source, int len) {
        int s_len = source.length();
        if (s_len > len) {
            source = source.substring(0, len);
            source = source + "...";
        }
        return source;
    }

    /**
     * 将url字符串进行指定解码.
     * 多用于地址栏的国际密码.
     * @param url 被解码的字符串.
     * @param enc 解码的格式.
     * @return 解码后的字符串.
     */
    public static String decodeURL(String url, String enc) {
        try {
            return URLDecoder.decode(url, enc);
        } catch (Exception e) {
            return "";
        }
    }

    /**
     * 将null字符串转化为""
     * @param s
     * @return
     */

    public static String getNotNullStr(String str) {
        if (str == null) {
            return "";
        } else if (StringUtils.equalsIgnoreCase("null",str)) {
            return "";
        } else {
            return str;
        }
    }
    
    /**
     * 将对象转化为""
     * @param s
     * @return
     */
    public static String getNotNullStr(Object object) {
        if (object == null) {
            return "";
        } else {
            return object.toString();
        }
    }
    
    /**
     * 获取int型的非“0”串.
     * @param value
     * @return
     * @since 2006-07-31
     */
    public static String getNotNullStr(int value){
        if(value == 0){
            return "";
        }
        
        return String.valueOf(value);
    }
    /**
     * 获取Long的非“0”串.
     * @param value
     * @return
     * @since 2006-07-31
     */
    public static String getNotNullStr(Long value){
        if(value == null || value.intValue()==0){
            return "";
        }
        
        return String.valueOf(value);
    } 
    
    /**
     * 去掉字符串前后空格，null返回""
     * @param str
     * @return
     */
    public static String getTrimStr(String str){
        if(str == null){
            return "";
        } else {
            return str.trim();
        }
    }
    
    /**
     * 将null转化为""
     * @param s
     * @return
     */

    public static String getNotNullLong(Long value) {
        String str =String.valueOf(value);
        if (str.equals("null")) {
            return "";
        } else {
            return str;
        }
    }
    /**
     * 将null转化为""
     * @param s
     * @return
     */

    public static String getNotNullDouble(Double value) {
        String str =String.valueOf(value);
        if (str.equals("null")) {
            return "";
        } else {
            return str;
        }
    }   
    /**
     * 将传入对象转换为数值int
     * @param obj 传入对象.
     * @return 
     */
    public static int getInt(Object obj) {
        int result = 0;
        if (obj != null) {
            try {
                result = Integer.parseInt(obj.toString());
            } catch (Exception e) {
                //do nothing, just ignore this
            }
        }
        return result;
    }

    /**
     * 获取升、降序.
     * @param queryMap  保存有键为"desc"的集合.
     * @return  键为"desc"的值为"1",返回" desc "，否则返回" asc "
     */
    public static String getDesc(Map queryMap) {
        String desc = (String) queryMap.get("desc");
        if (desc.equals(DESC)) {
            desc = " desc ";
        } else {
            desc = " asc ";
        }
        return desc;
    }
   
    /**
     * 字符串转换，转换null
     */
    public static String replaceNull(Object value) {
        if (value == null)
            return "&nbsp;";
        else if(value.equals(Globals.GLOBAL_SELECT))
            return "&nbsp;";
        else
            return value.toString();
    }

    /**
     * 将字符串转换为Long(异常时返回0)
     * @param value
     * @return
     * @author Sun
     * @since  2006-07-18
     */
    public static Long getLong(String value) {
        return getLong(value, 0);
    }

    /**
     * 将字符串转换为Long
     * @param value 待转换的字符串.
     * @param defaultValue 出现异常时默认返回的值.
     * @return
     * @author Sun
     * @since  2006-07-18
     */
    public static Long getLong(String value, int defaultValue) {
        Long result = new Long(defaultValue);
        if (value == null || value.trim().length() == 0) {
            return result;
        }
        try {
            result = Long.valueOf(value);
        } catch (Exception e) {
            result = new Long(defaultValue);
        }

        return result;
    }
    
    /**
     * 返回非Null的Long值.
     * @param value
     * @param defaultValue
     * @return
     * @since   2008-07-04
     * @author  Sunm
     */
    public static Long getLong(Long value, long defaultValue) {
        if(value==null) {
            return Long.valueOf(defaultValue);
        }
        
        return value;
    }
    
    public static Long getLong(Long value) {
        return getLong(value,0);
    }
    
    /**
     * 返回非Null的Integer值.
     * @param value
     * @param defaultValue
     * @return
     * @since   2008-07-04
     * @author  Sunm
     */
    public static Integer getInteger(Integer value, int defaultValue) {
        if(value==null) {
            return Integer.valueOf(defaultValue);
        }
        
        return value;
    }
    
    public static Integer getInteger(Integer value) {
        return getInteger(value, 0);
    }
    
    /**
     * 获取加密后的字符串(MD5加密)
     * @param code  待加密的字符串.
     * @return
     */
    public static String getSecurityString(String code) {
        if(code==null || code.length()==0)   return null;
        MD5 md5 = new MD5();
        return md5.getMD5ofStr(code);
    }
    
    /**
     * 取指定精度的除运算结果.
     */
    public static double div(int n1, int n2, int scale){
        double result = 0;
        BigDecimal b1 = new BigDecimal(n1);
        BigDecimal b2 = new BigDecimal(n2);
        result = b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
        
        return result;
    }
    
    /**
     * 缩放指定的整数.
     */
    public static int scale(int n1, double scale){
        return (int)Math.round(n1*scale);
    }

    /**
     * 校验字符串是否匹配正则表达式.
     * @param input 字符串.
     * @param pattern   正则表达式.
     * @return
     */
    public static boolean isMatch(String input, String pattern) {
        if (input == null || pattern == null)
            return false;
        Pattern ptn = null;
        try {
            ptn = Pattern.compile(pattern);
        } catch (PatternSyntaxException e) {
            //ignore
        }

        Matcher matcher = ptn.matcher(input);
        if (matcher.matches()) {
            return true;
        } else {
            return false;
        }
    }
    
    /**
     * 字符串在数组内.
     * @param field 字符串.
     * @param candidates    数组.
     * @return
     */
    public static boolean in(String field, String[] candidates) {
        if(StringUtil.isEmpty(field) || candidates==null) {
            return false;
        }
        for(int i = 0;i < candidates.length;i++){
            String candidate = candidates[i];
            if(field.equalsIgnoreCase(candidate)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 设置集合内对象的修改人、修改日期.
     */
    public static void setProperty(HttpServletRequest request,Set set,String name,Object value) throws Exception{
        for(Iterator iter = set.iterator();iter.hasNext();){
            Object object = (Object)iter.next();
            PropertyUtils.setProperty(object,name,value);
        }
    }
    
    /**
     * 获取对象属性.
     */
    public static String getProperty(Object object, String property) throws Exception{
        return (String)PropertyUtils.getProperty(object,property);
    }
    
    /**
     * 将源对象属性值设置到目标对象中的同名属性中.
     */
    public static void setProperty(Object targetObj, Object srcObj, String property) throws Exception{
        setProperty(targetObj,property,srcObj,property);
    }
    
    /**
     * 将源对象属性值设置到目标对象中的其他属性中.
     */
    public static void setProperty(Object targetObj, String targetProperty, Object srcObj, String srcProperty) throws Exception{
        Object value = PropertyUtils.getProperty(srcObj,srcProperty);
        PropertyUtils.setProperty(targetObj,targetProperty,value);
    }
    
    /**
     * 将十六进制编码字符改为解码字符.
     * @param hex   经过十六进制编码的字符串.
     * @return
     * @throws DecoderException
     */
    public static String decodeHex2Str(String hex) throws DecoderException {
        if(StringUtil.isEmpty(hex)) {
            return hex;
        }
        byte[] bs = Hex.decodeHex(hex.toCharArray());
        try{
            return new String(bs,"utf-8");
        }catch(UnsupportedEncodingException e){
            e.printStackTrace();
        }
        return "";
    }
    
    /**
     * 将字符编码为十六进行字符.
     * @param hex   经过十六进制编码的字符串.
     * @return
     * @throws DecoderException
     */
    public static String encodeStr2Hex(String str) {
        if(StringUtil.isEmpty(str)) {
            return str;
        }
        String result = "";
        try{
            result = String.valueOf(Hex.encodeHex(str.getBytes("utf-8")));
            }catch(UnsupportedEncodingException e){
                e.printStackTrace();
            }
            return result;
    }
    
    public static String genUUID(){
    	String str = UUID.randomUUID().toString();
    	str = str.replace("-", "");
    	
    	return str;
    }
    
    public static String genRandomUUID() {
    	UUID uuid=UUID.randomUUID();
    	
    	return uuid.toString().replaceAll("-", "");
    }
}

/*
 * *****************************VSS GENERATED
 * HISTORY***************************** $History: $
 * *******************************************************************************
 */